package com.nondo.dean.order.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.nondo.dean.auth.common.TokenPrincipalProvider;
import com.nondo.dean.common.tool.AliyunOssTool;
import com.nondo.dean.order.common.OrderTip;
import com.nondo.dean.order.domain.Cart;
import com.nondo.dean.order.domain.CartExample;
import com.nondo.dean.order.mapper.CartMapper;
import com.nondo.dean.order.model.ConsigneeBean;
import com.nondo.dean.order.model.ProductMixBean;
import com.nondo.dean.order.model.UserBean;
import com.nondo.dean.order.model.param.ConfirmOrderParam;
import com.nondo.dean.order.model.result.AppCartResult;
import com.nondo.dean.order.model.result.ConfirmOrderResult;
import com.nondo.dean.order.model.result.ProductResult;

/**
 * 购物车管理业务类
 * 
 * @author zhaoljin
 * @date 2018年4月16日
 */
@Component
public class CartService {

    @Autowired
    private CartMapper cartMapper;
    
    @Autowired
    private ProductService produtService;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private AliyunOssTool aliyunOssTool;
    
    @Autowired
    TokenPrincipalProvider principalProvider;

    /**
     * 插入购物车
     * @param cart
     * @return
     */
    @Transactional
    public String addCart(Cart cart) {
        // 获取登录用户ID
        Integer userId = userService.getLoginUserId();
        cart.setUserId(userId);
        // 检测库存
        Integer productId = cart.getProductId();
        Integer num = cart.getNum();
        String message = checkProductStock(productId, num);
        if (message != null) {
            throw new RuntimeException(message);
        }
        // 相同产品合并
        CartExample example = new CartExample();
        CartExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, cart);
        List<Cart> cartList = cartMapper.selectByExample(example);
        // 保存购物车
        if (CollectionUtils.isEmpty(cartList)) {
            cartMapper.insertSelective(cart); 
        } else {
            for (Cart cartDb : cartList) {
                cartDb.setNum(cartDb.getNum()+1);
                cartDb.setNote(cart.getNote());
                cartMapper.updateByPrimaryKeySelective(cartDb);
            }
        }
        
        return message;
    }

    /**
     * 修改购物车
     * @param cart
     * @return
     */
    @Transactional
    public String updateCart(Cart cart) {
        // 检测库存
        Integer productId = cart.getProductId();
        Integer num = cart.getNum();
        String message = checkProductStock(productId, num);
        cartMapper.updateByPrimaryKeySelective(cart);
        return message;
    }

    /**
     * 检测产品库存
     * @param cart
     * @return 库存不足的提示
     */
    public String checkProductStock(Integer productId, Integer num) {
        ProductResult productResult = null;
        productResult = produtService.getProductBeanById(productId);
        if (productResult.getId() == null) {
            return OrderTip.PRODUCT_NOT_EXIST;
        }
        if (productResult.getStock() < num) {
            return OrderTip.STOCK_NOT_ENOUGH;
        }
        return null;
    }

    /**
     * 按照主键ID查询购物车
     * @param id
     * @return
     */
    public Cart selectCart(Integer id) {
        return cartMapper.selectByPrimaryKey(id);
    }

    /**
     * 购物车分页查询列表
     * @param offset
     * @param limit
     * @param cart
     * @return
     */
    public List<Cart> getCartList(int offset, int limit, Cart cart) {
        CartExample example = new CartExample();
        example.setOrderByClause("create_date DESC");
        RowBounds rowBounds = new RowBounds(offset, limit);
        CartExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, cart);
        return cartMapper.selectByExampleWithRowbounds(example, rowBounds);
    }

    /**
     * 购物车总数统计
     * @param cart
     * @return
     */
    public Long count(Cart cart) {
        CartExample example = new CartExample();
        CartExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, cart);
        return cartMapper.countByExample(example);
    }

    /**
     * 组装查询条件
     * @param criteria
     * @param cart
     */
    void setCriteria(CartExample.Criteria criteria, Cart cart) {
        if (cart != null) {
            if (cart.getId() != null)
                criteria.andIdEqualTo(cart.getId());
            if (cart.getUserId() != null) 
                criteria.andUserIdEqualTo(cart.getUserId());
            if (cart.getProductId() != null)
                criteria.andProductIdEqualTo(cart.getProductId());
        }
        criteria.andDelFlagEqualTo(String.valueOf(0));
    }
    
    /**
     * 购物车结算页面数据
     * @param cartIds 购物车ID字符串，多个用逗号隔开
     * @return {@link AppCartResult}
     */
    public AppCartResult getCartResult(String cartIds) {
        AppCartResult cartResult = new AppCartResult();
        // 查询未提交的购物车列表
        int total = 0;
        List<Cart> cartList = getCartList(cartIds);
        BigDecimal totalPrice = new BigDecimal(0.00);
        List<AppCartResult.CartBean> cartBeanList = new ArrayList<AppCartResult.CartBean>();
        for (Cart cart : cartList) {
            Integer productId = cart.getProductId();
            ProductResult productResult = produtService.getProductBeanById(productId);
            if (productResult.getId() != null) {
                AppCartResult.CartBean cartBean = AppCartResult.covertToBean(productResult);
                cartBean.setIsMix(isMix(productId));
                cartBean.setMainImage(aliyunOssTool.getImgUrl(productResult.getMainImage()));
                BigDecimal salePrice = productResult.getSalePrice();
                cartBean.setNote(cart.getNote());
                cartBean.setNum(cart.getNum());
                cartBean.setId(cart.getId());
                total += cartBean.getNum();
                // 计算产品价格合计后赋值
                totalPrice = calculateAmount(totalPrice, salePrice, cartBean.getNum());
                cartBeanList.add(cartBean);
            }
        }
        cartResult.setCartList(cartBeanList);
        cartResult.setTotal(total);
        cartResult.setTotalPrice(totalPrice);
        return cartResult;
    }

    /**
     * 计算产品价格和总金额
     * @param totalPrice 总金额
     * @param salePrice 产品单价
     * @param productNum 产品数量
     * @return 金额合计
     */
    public BigDecimal calculateAmount(BigDecimal totalPrice, BigDecimal salePrice, Integer productNum) {
        BigDecimal num = new BigDecimal(productNum);
        totalPrice = totalPrice.add(salePrice.multiply(num));
        return totalPrice;
    }

    /**
     * 获取购物车列表
     * @param cartIds 购物车ID字符串，多个用逗号隔开
     * @return 查询结果 List<{@link Cart}>
     */
    private List<Cart> getCartList(String cartIds) {
        CartExample example = new CartExample();
        example.setOrderByClause("ID DESC");
        CartExample.Criteria criteria = example.createCriteria();
        Integer userId = userService.getLoginUserId();
        criteria.andUserIdEqualTo(userId);
        if (StringUtils.isNotBlank(cartIds)) {
            String[] cartIdArray = cartIds.split(",");
            List<Integer> cartIdList = new ArrayList<Integer>();
            for (String cartId : cartIdArray) {
                cartIdList.add(Integer.parseInt(cartId));
            }
            criteria.andIdIn(cartIdList);
        }
        criteria.andDelFlagEqualTo(Cart.DEL_FLAG_NORMAL);
        List<Cart> cartList = cartMapper.selectByExample(example);
        return cartList;
    }

    
    /**
     * 获取确认订单数据
     * @param {@link ConfirmOrderParam}
     * @return {@link ConfirmOrderResult}
     */
    public ConfirmOrderResult getConfirmOrderDetail(ConfirmOrderParam orderParam) {
        ConfirmOrderResult confirmOrder = new ConfirmOrderResult();
        // 查询收货人信息
        Integer userId = userService.getLoginUserId();
        UserBean userBean = userService.getUserBeanById(userId);
        ConsigneeBean consignee = ConsigneeBean.covertToBean(userBean);
        confirmOrder.setConsignee(consignee);
        // 根据类型加载下单信息
        Integer type = orderParam.getType();
        AppCartResult cartResult = new AppCartResult();
        if (type == 1) { // 立即购买进入
            cartResult = getCartResult(orderParam);
            cartResult.setTotal(orderParam.getNum());
        } else if (type == 2) { // 从购物车加载
            String cartIds = orderParam.getCartIds();
            cartResult = getCartResult(cartIds);
        }
        confirmOrder.setCartResult(cartResult);
        return confirmOrder;
    }

    /**
     * 立即购买确认订单
     * @param {{@link ConfirmOrderParam}
     */
    private AppCartResult getCartResult(ConfirmOrderParam orderParam) {
        AppCartResult cartResult = new AppCartResult();
        Integer productId = orderParam.getProductId();
        ProductResult productResult = produtService.getProductBeanById(productId);
        BigDecimal totalPrice = new BigDecimal(0.00);
        List<AppCartResult.CartBean> cartBeanList = new ArrayList<AppCartResult.CartBean>();
        if (productResult.getId() != null) {
            AppCartResult.CartBean cartBean = AppCartResult.covertToBean(productResult);
            cartBean.setMainImage(aliyunOssTool.getImgUrl(productResult.getMainImage()));
            BigDecimal salePrice = productResult.getSalePrice();
            cartBean.setNote(orderParam.getNote());
            cartBean.setNum(orderParam.getNum());
            cartBean.setId(0);
            cartBeanList.add(cartBean);
            cartResult.setCartList(cartBeanList);
            // 计算总金额
            totalPrice = calculateAmount(totalPrice, salePrice, cartBean.getNum());
        }
        cartResult.setTotalPrice(totalPrice);
        return cartResult;
    }
    
    /**
     * 产品是否参与组合售卖
     * @param productId
     * @return 1是0否
     */
    private int isMix(Integer productId) {
        List<ProductMixBean> productMixList = produtService.getProductMixList(productId);
        return (CollectionUtils.isNotEmpty(productMixList)) ? 1 : 0;
    }
    
}
